package gu.sql2java.wherehelper.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import gu.sql2java.wherehelper.CompareOp;
import gu.sql2java.wherehelper.RangeType;
import gu.sql2java.wherehelper.VarTestType;

import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;

/**
 * WhereHelper 数值范围算述比较表达式注解
 * @author guyadong
 * @since 3.25.0
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
@Repeatable(Ranges.class)
public @interface Range{
	/**
	 * test表达式执行为true时生成的数值范围比较表达式
	 */
	String test() default "true";
	/**
	 * 要求为null的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为空则默认为'true'
	 */
	String[] testNullVars() default{};
	/**
	 * 要求不为null的变量名列表,['var1','var2'],等价于'null!=${var1} && null!=${var2}',为空则默认为'true'
	 */
	String[] testNonullVars() default{};
	/**
	 * 要求为{@code null}或空的变量名列表,['var1','var2'],等价于'isEmpty(${var1}) && isEmpty(${var2})',为空则默认为'true'
	 */
	String[] testEmptyVars() default{};
	/**
	 * 要求不为{@code null}或空的变量名列表,['var1','var2'],等价于!'isEmpty(${var1}) && !isEmpty(${var2})',为空则默认为'true'
	 */
	String[] testNoEmptyVars() default{};
	/**
	 * 要求为{@code true}的变量名列表,['var1','var2'],等价于'isTrue(${var1)} && isTrue(${var2})',为空则默认为'true'
	 */
	String[] testTrueVars() default{};
	/**
	 * 要求为{@code false}的变量名列表,['var1','var2'],等价于'isFalse(${var1}) && isFalse(${var2})',为空则默认为'true'
	 */
	String[] testFalseVars() default{};
	/**
	 * 定义基于{@link #testType()}的条件测试表达式变量名
	 */
	String testVar() default "";
	/**
	 * 变量测试类型
	 */
	VarTestType testType() default VarTestType.EQUAL;
	/**
	 * 条件测试操作符
	 */
	CompareOp testOp() default CompareOp.EQ ;
	/**
	 * 变量条件测试的目标值 
	 */
	String testValue() default "";
	/**
	 * 为{@code true}生成表达式对{@link #testValue()} 以字符串对头尾增加单引号,
	 * {@link #testRefValue()}为{@code true}时忽略
	 * @since 3.25.0
	 */
	boolean testQuote() default false;
	/**
	 * 为{@code true}生成表达式对{@link #testValue()} 视为变量名
	 */
	boolean testRefValue() default false;
	/**
	 * 执行范围算术比较的(数据库)字段名
	 */
	String field();
	/**
     *  左侧范围(较小值)变量名,为空时如果{@link #lowerVarSuffix()}不为空使用默认值:{@code field+lowerVarSuffix},否则忽略
     */
    String lowerVar() default "";
    /**
     *  左侧范围(较小值)变量名后缀,参见{@link #lowerVar()}
     */
    String lowerSuffix() default "_min";
    /**
	 * 为{@code true}生成SQL表达式对{@link #lowerVar()}视为变量名,否则视为常量
	 */
	boolean lowerRefValue() default true;
	/**
     *  右侧范围(较大值)变量名,为空时如果{@link #upperVarSuffix()}不为空使用默认值:{@code field+upperVarSuffix},否则忽略
     */
    String upperVar() default "";
    /**
     *  右侧范围(较大值)变量名后缀,参见{@link #lowerVar()}
     */
    String upperSuffix() default "_max";
	/**
	 * 为{@code true}生成SQL表达式对{@link #upperVar()} 视为变量名,否则视为常量
	 */
	boolean upperRefValue() default true;
	/**
	 * 数值范围类型
	 */
    RangeType rangeType() default RangeType.OPENCLOSE;
    /**
     * 为{@code true}生成表达式对数值以字符串对象头尾增加单引号
     */
    boolean quote();
	/**
     * 是否对{@link #field()}指定的变量执行判断空检查,此参数对于类型为String的参数有影响<br>
     * <table border="1">
     * <tr><th align=left>值</th><th align=left>说明</th></tr>
     * <tr><td>{@code true} </td><td>{@link #field()}指定的变量执行判断空检查</td></tr>
     * <tr><td>{@code false}</td><td>只需要判断是否为{@code null}</td></tr>
     * <tr><td>空</td><td>使用{@link #quote()}的值</td></tr>
     * </table>
     */
    boolean[] checkFieldEmpty() default {};
}
